# Copyright (C) 2020, 2021 Maxime Devos
# SPDX-License-Identifier: FSFAP
# Copying and distribution of this file, with or without modification,
# are permitted in any medium without royalty provided the copyright
# notice and this notice are preserved.  This file is offered as-is,
# without any warranty.

* scheme-GNUnet: a partial Scheme port of GNUnet
  TODO: ask upstream of use of name is acceptable
  TODO: more bindings, less duplication
  TODO: document directory & meta data format
* How to build & install
  #+BEGIN_SRC shell
    # When using Guix
    # (XXX make dependency on Guix itself optional)
    guix environment -l guix.scm

    autoreconf -vif
    ./configure
    make
    make check
  #+END_SRC
  TODO install
* things that work
  TODO: test suite for download & publish.
  TODO (elsewhere): GNUnet service definitions for Guix in container

** DONE publishing store items
   (Script: gnu/gnunet/scripts/publish-store.scm)
   (Described in ROADMAP.org)

   We cheat by calling the gnunet-publish binary.
   Use this to publish a directory from the store!
** DONE downloading store items
   (Script: gnu/gnunet/scripts/download-store.scm)
   (Described in ROADMAP.org)

   The inverse of the former, to be implemented.
   When implemented, contact guix-devel on how
   to proceed.  Either creates a directory structure
   or a nar.
* Purposes
  + for use by Guix and disarchive
  + bit-for-bit reproducibility in directory creation
  + a nice Scheme interface to GNUnet!
* Modules
  + gnu/gnunet/directory.scm: directory construction
  + gnu/gnunet/concurrency/update.scm: a box with a value,
    that can be updated, resulting in a new box.  Updates
    can be waited upon.
  + gnu/gnunet/utils/platform-enum.scm: Platform-specific
    C-style enum values.
  + gnu/gnunet/concurrency/repeated-condition: different type
    of conditions (TODO describe better)
** Tags
   + spec: it is unknown if this will turn out to be a practical abstraction.
   + why: it remains to be seen if these modules will have any use
   + test: these modules have (passing) tests
   + good: these modules, abstractions ... are practical, and will not be scrapped
     (tweaks might still be possible, and the modules could still have missing
     functionality)
   + wart: these modules have some ‘unniceties’ (warts).  This does /not/ prevent
     the ‘good’ tag.

** Message queues                                                      :spec:

   Message queues have a handler for normal incoming messages and for errors.
   If a transport receives an incoming message, it should add it (‘inject’)
   to the incoming messages, which may result in a message handler being
   called. The user of the queue can also try to cancel sending a message
   and will receive a notification when the message cannot be unsent anymore.

   Message queues can be used concurrently. (TODO destruction)

   + gnu/gnunet/mq/envelope.scm: a wrapper around a message, with a callback
     for cancelling the sending of the message (if not too late) and a callback
     for notifying it cannot be unsent anymore.
   + gnu/gnunet/mq/prio-prefs.scm: message priorities & preferences

     Preferences: is out-of-order allowed or not,
     should the message be corked or not ...
   + gnu/gnunet/mq/handler.scm: what to do in
     response to a message.

     Different message types may need need different
     capabilities; the interposition can be used to adjust
     the ambient authority appropriately.
   + gnu/gnunet/mq.scm: the message queue itself!
   + gnu/gnunet/mq-impl/stream.scm: generic implementation on top of
     Guile's port abstraction.

   + TODO actual queues?  Maybe we don't need them?
   + TODO filling the queues

   Message queue implementations based on streams I/O can use
   (gnu gnunet utils tokeniser), to split the message stream
   into separate messages.
** List of errors

   Not all errors indicate something is wrong.

   Input errors
   + input:regular-end-of-file

     The end-of-file was encountered and not unexpected
     (compare with input:premature-eof).
   + input:premature-end-of-file

     The end-of-file was encountered, but unexpected.
     More specifically, a message was being read.
   + input:overly-small type size

     The message size in the header was smaller than the minimal
     message size.

   Input errors (decoding)
   + TODO verification failed, unknown message type
** Configuration                                                  :test:good:
   + gnu/gnunet/config/parser.scm: Parse configuration files.
   + gnu/gnunet/config/expand.scm: Perform variable expansion.
   + gnu/gnunet/config/value-parser.scm: Parse configuration values.
     TODO: value->data, value->relative-time
   + gnu/gnunet/config/db.scm: Quaject for configurations.

   TODO: modifying, update notifications, loading ...
** Network structures                                             :good:wart:
   Features:

   + structures are always architecture-independent
     (no possible dependencies on the C ABI)
   + big / little endianness distinction
   + (almost) no runtime overhead over raw
     slice-u8-ref & friends when using syntax API

     (Some overhead is incurred due to type-checking)
     TODO: verify expanded code
   + structures can have various meta data
     (e.g. docstring)  TODO write emacs functions
     for looking up docstrings etc.

   Not features (in contrast with scheme-bytestructures):
   - not extensible with new kinds of network structure types.

   How to use:
   + define network structures in a (... struct) module
     using (gnu gnunet netstruct syntactic) or
     (gnu gnunet netstruct procedural)
   + use network structures /outside/ the (... struct) module
     using (gnu gnunet netstruct syntactic)
     or (gnu gnunet netstruct procedural) module.

     The former is preferred as offsets and sizes etc.
     are inlined

     TODO: make sure no references to (... struct) modules
     are created when accessing network structures with
     (gnu gnunet netstruct syntactic).
** GNUnet network structures                                           :good:
   + gnu/gnunet/nse/struct.scm: network size estimation
   + gnu/gnunet/hashcode/struct.scm: hashes
   + gnu/gnunet/crypto/struct.scm: signatures, keys, nonces ...
   + gnu/gnunet/util/struct.scm: various things
** More refined IP, TCP, UDP, ...                             :test:good:why:
   + gnu/gnunet/icmp/struct.scm: ICMP packet types & codes
     (incomplete, to be used for error messages)
   + gnu/gnunet/util/cmsg.scm: Constructing & analysing
     ancillary messages (likewise)

   TODO: IP_PKTINFO for interface address, scope ...
   TODO: message queue based upon this
   TODO: nice abstraction for network errors
* Conventions
** Fibers, capabilities and ambient authority
   Modules are expected to use ‘fibers’ for concurrency.

   They should not introduce any ambient authority,
   and avoid implicit use of pre-existing ambient authority
   (e.g. current-output-port, the current persona).

   To avoid accidental reuse of capabilities accross
   modules, do not call callbacks where it can be avoided.
   Consider conditions for signalling an event occurred instead.
** Documenting modules
   Add a little information to ‘* Modules’.
** Fiddling with options
   Options like ‘priority’, ‘anonymity’, ‘replication’
   and ‘no-index’ should be ‘passed’ using SRFI-39 parameters,
   and not with positional or keyword arguments,
   as they are just passed through unchanged most of the time.
** Tests
   Read --> [[https://sqlite.org/testing.html][How SQLite Is Tested]] (accessed: 2021)

   This GNUnet implementation isn't quite that well-tested,
   and most likely won't be for the foreseeable future.  However,
   when defining new code, try to define the following kind of
   tests where reasonable (non-exhaustive);

   + verify (iso-)morphisms and similar properties are upheld (e.g.
     using guile-quickcheck for generating test cases).  E.g. if there
     is a conversion function f : X -> Y and g : Y -> X, verify
     (compose f g) = id = (compose g f).  Verify morphisms like
     (length (append x y)) = length (x) + length (y).
   + Run mutation tests!  That is, replace < with <=, 0 by 1, a variable
     reference ‘i’ by a variable reference ‘j’, swap destination and source
     arguments ... and verify whether the tests catch these little mutations!
   + Verify argument checking!
     (basic non-dependent type checking, in-bounds, right capabilities ...,
     appropriate exception).   An &assertion is usually fine, though
     occassionally a more informative condition may be in-place.

* Wishlist
  + Schemification

    Many procedures are less-or-more directly transcribed
    from the imperative C source code. Less is preferred over
    more.
  + Less copying bytevectors around

    Bytevectors are often duplicated to preserve safety in presence of
    buggy / insecure / hostile code in a sandbox.
* License
  See the LICENSES directory for license text,
  and each file with source code for the license and copyright text.
  Most code is under the Affero General Public License (v3 or later),
  see each source file for details.
* Contact
  Maintainer: Maxime Devos <maximedevos@telenet.be>.
  PGP fingerprint: C1F3 3EE2 0C52 8FDB 7DD7 011F 49E3 EE22 1917 25EE.
  Patches may be sent as formatted by `git format-patch`.
  E-mail messages should ideally by be signed with PGP (or GnuPG, etc.).

  Presuming I'm using the word ‘notoriously’ correctly,
  announcements by the maintainer of ‘taking a break’ from
  Guix+GNUnet hacking are notoriously unreliable.  I suggest
  you disregard them (but note that sometimes these are
  actually true).
